package com.blockchain.coupon.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import com.blockchain.coupon.mapper.MerchantMapper;
import com.blockchain.coupon.mapper.SettlementOperationMapper;
import com.blockchain.coupon.po.SettlementApplication;
import com.blockchain.coupon.rpc.Web3;
import org.springframework.beans.factory.annotation.Autowired;

import com.blockchain.coupon.mapper.BankMapper;
import com.blockchain.coupon.po.BankStaffCustom;
import com.blockchain.coupon.po.MerchantCustom;
import com.blockchain.coupon.po.MerchantRegisterCustom;
import com.blockchain.coupon.po.SettlementOperationCustom;
import com.blockchain.coupon.service.BankService;
import com.blockchain.coupon.sha3.Sha3;
import com.blockchain.coupon.util.DateUtil;
import com.blockchain.coupon.util.Encryption;
import com.blockchain.coupon.util.ReadAccount;

public class BankServiceImpl implements BankService {
	
	@Autowired
	private SettlementOperationMapper settlementOperationMapper;
	
	@Autowired
	private MerchantMapper merchantMapper;
	
	@Autowired
	private BankMapper bankMapper;

//	查询结算券申请列表
	public  List<SettlementApplication> querySettlementApplicationList(String id) throws Exception {
		// TODO Auto-generated method stub
		BankStaffCustom bankStaffCustom=bankMapper.queryBankStaffById(id);
		if(bankStaffCustom!=null){
			if(bankStaffCustom.getPosition().equals("1")) {
				return settlementOperationMapper.querySFCList();
			}else{
				return settlementOperationMapper.querySSCList();
			}
		} else{
			return null;
		}
	}

//	查询结算券提现列表
	public List<SettlementApplication> querySettlementWdList(String id) throws Exception {
		// TODO Auto-generated method stub
		BankStaffCustom bankStaffCustom=bankMapper.queryBankStaffById(id);
		if(bankStaffCustom!=null){
			if(bankStaffCustom.getPosition().equals("1")) {
//				返回提现初审列表
				return settlementOperationMapper.querySWDFList();
			} else {
//				返回提现复审列表
				return settlementOperationMapper.querySWDSList();
			}
		}
		return null;
	}

/**
 * 结算券初审结果更新
 * 因为结算券申请初审和结算券提现初审执行的操作是一样的
 * 所以，这里就统一使用了一个方法	
 */
	public String updateSettlementFirstCheck(SettlementOperationCustom settlementOperationCustom) throws Exception {
		// TODO Auto-generated method stub
		settlementOperationCustom.setOperationTime(DateUtil.getCurrentTime());
		try {
			settlementOperationMapper.updateSettlementFirstCheck(settlementOperationCustom);
			return "1";
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return "0";
		}
	}

/**
 * 结算券复审之后，商户表中的结算券余额需要同时更新，
 * isAdd为true,则执行的操作是结算券申请，商户的结算券余额增加
 *  isAdd为false，则执行的操作是结算券提现，商户的结算券余额减少
 */
	public String updateSettlementSecondCheck(SettlementOperationCustom soc,boolean isAdd) throws Exception {
		// TODO Auto-generated method stub
		soc.setRecheckTime(DateUtil.getCurrentTime());
		try {
			settlementOperationMapper.updateSettlementSecondCheck(soc);
			
//			查询商户结算券余额
			int settlementBalance=merchantMapper.querySettlementBalance(soc.getMerchantId());
			MerchantCustom mc=new MerchantCustom();
			mc.setId(soc.getMerchantId());
			if(isAdd){
				mc.setSettlementBalance(settlementBalance+soc.getOperationAmount());
			}else{
				mc.setSettlementBalance(settlementBalance-soc.getOperationAmount());
			}
//			更新商户结算券余额
			merchantMapper.updateSettlementBalance(mc);
			
			
//			String functionName = "Main.approve";
//			String[] content = {"1","0x48944e22a3d616b441ca58db68db9b8f4d967dcd","100","true"};
//			String from = "0x36168ff2e45e6906601ae696a26e0a0f77d3a778";
//			String to = "0xde7f563c45db2bb8ca9455f347620999c61e40e0";//main contract address
//			sendTransactionMap(functionName, content, from, to);
			
//			更新区块链上的结算券余额
			String functionName = "Main.approve";
			String[] type = {"bytes","address","uint","bool"};
			String[] content;
			MerchantCustom secMc=merchantMapper.queryPKAndConAddr(soc.getMerchantId());
			if(isAdd){
				content = new String[]{"1",secMc.getContractAddress(),soc.getOperationAmount()+"","true"};
			}else{
				content = new String[]{"1",secMc.getContractAddress(),soc.getOperationAmount()+"","false"};
			}
			String from = ReadAccount.getAccount("bankAccount");  //银行公钥
			String to = ReadAccount.getAccount("mainContractAddress");   //主合约地址
			String txHash= Web3.sendTransactionMap(functionName, content, from, to);
			
//			检测交易是否得到确认
			String[] content3 = {txHash};
			String finish="null";
			while(finish.equals("null")){
				finish = Web3.universalCall("eth_getTransactionReceipt", null, content3, null);
			}
			return "1";
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return "0";
		}
	}
	
	
	
//	查询注册信息尚未审核的商户信息
	public List<MerchantRegisterCustom> queryUncheckMerchant() throws Exception {
		// TODO Auto-generated method stub
		return merchantMapper.queryUncheckMerchant();
	}
	
//	更新注册待审核的商户的信息
	public List<MerchantRegisterCustom> updateMerchantRegisterInfo(MerchantRegisterCustom merchantRegisterCustom)
			throws Exception {
//		更新商户注册表状态
		merchantMapper.updateMerchantRegisterStatus(merchantRegisterCustom);
		if(merchantRegisterCustom.getStatus().equals("1")){
//			向商户表中插入一条记录
			try {
				MerchantRegisterCustom mrc=merchantMapper.queryMerInfoFromRegisterById(merchantRegisterCustom.getId());
				MerchantCustom mc=new MerchantCustom();
				mc.setId(UUID.randomUUID().toString());
				mc.setAccount(mrc.getAccount());
				mc.setPassword(mrc.getPassword());
				mc.setSalt(mrc.getSalt());
				mc.setName(mrc.getName());
				mc.setAddress(mrc.getAddress());
				mc.setLicence(mrc.getLicence());
				mc.setLegalEntityName(mrc.getLegalEntityName());
				mc.setBusinessScope(mrc.getBusinessScope());
				

//				获取银行账户、主合约地址、商户账户
				String bankAccount=ReadAccount.getAccount("bankAccount");
				String mainContractAddress=ReadAccount.getAccount("mainContractAddress");
				String merchantAccount=ReadAccount.getAccount("merchantAccount");
			    mc.setPublicKey(merchantAccount);
				
//				创建商户
				String functionName = "Main.createMerchant";
				String[] content = {merchantAccount};  //商户公钥
				String from = bankAccount;  //交易发送方
				String to = mainContractAddress;  //主合约地址
				String txHash=Web3.sendTransactionMap(functionName, content, from, to);
				
				String[] content3 = {txHash};
				String finish="null";
				while(finish.equals("null")){
					finish = Web3.universalCall("eth_getTransactionReceipt", null, content3, null);
				}
				
				String functionName1 = "Main.getMerchantLatest";
				String[] content1 = null;  //商户公钥
				String from1 = bankAccount;  //交易发送方
				String to1 = mainContractAddress;  //主合约地址
//				返回商户合约地址
				List<String> merchantContractAddress=Web3.decodeReturnValue("address", Web3.getValueMap(functionName1, content1, from1, to1));
				mc.setContractAddress(merchantContractAddress.get(0));
				
//				添加商户
				merchantMapper.insertMerchant(mc);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				return queryUncheckMerchant();
			}
			
		}
		return queryUncheckMerchant();
	}

//	员工注册
	public String insertBankStaff(BankStaffCustom bankStaffCustom) throws Exception {
		// TODO Auto-generated method stub
		try {
			BankStaffCustom bsc=bankMapper.queryBankStaffByAccount(bankStaffCustom.getAccount());
			if(bsc!=null){
				return "0";//用户已经存在
			}
			bankStaffCustom.setId(UUID.randomUUID().toString());
			bankStaffCustom.setSalt(Encryption.createSalt());
			bankStaffCustom.setPassword(Sha3.sha3(bankStaffCustom.getPassword()+bankStaffCustom.getSalt()));
			bankMapper.insertBankStaff(bankStaffCustom);
			return "1";
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return "0";
		}
		
	}
	
//	员工登录
	public Map<String, String> login(String account,String password)throws Exception{
		BankStaffCustom bsc=bankMapper.queryBankStaffByAccount(account);
		Map<String, String> m=new HashMap<String, String>();
		if(bsc==null){
			m.put("resultCode", "0");
			return m;
		}else{
			if((Sha3.sha3(password+bsc.getSalt())).equals(bsc.getPassword())){
				m.put("resultCode", "1");
				m.put("position", bsc.getPosition());
				m.put("id", bsc.getId());
				return m;
			}else{
				m.put("resultCode", "0");
				return m;
			}
		}
	}
	
}
